package main;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

public class Process extends Thread{
	
	
	private ArrayList<Page> pagesIndex = new ArrayList();
	
	public static int MEMORY_SIZE = 256;
	
	private ThePlace onePlace;
	private ThePlaceLRU onePlaceLRU;
	private ThePlaceWSClock onePlaceWSClock;
	private ThePlaceRandom onePlaceRandom;
	private int number;
	private int mode;
	private int faults = 0;
	private int reads = 0;
	private int writes = 0;
	private int init = 0;
	
	public Process(ThePlace one, int number) {
		onePlace = one;
	    this.number = number;
	}
	public Process(ThePlaceLRU one, int number) {
		onePlaceLRU = one;
	    this.number = number;
	}
	public Process(ThePlaceWSClock one, int number) {
		onePlaceWSClock = one;
	    this.number = number;
	}
	public Process(ThePlaceRandom one, int number) {
		onePlaceRandom = one;
	    this.number = number;
	}
	public void run(){
	    
		int value = 0;
	    //int processSize = (int) (Math.random() * 128) + 1;
	    int processSize = 64;
	    File writeLog = new File("writeLog.txt");
	    File readLog = new File("readLog.txt");
	    File pageFautlLog = new File("pageFaultLog.txt");
	    File log = new File("log.txt");
	    
	    
	    PrintWriter outLog = null;
		try {
			outLog = new PrintWriter(new FileWriter(log, true));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
	    PrintWriter outWrite = null;
		try {
			outWrite = new PrintWriter(new FileWriter(writeLog, true));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	    PrintWriter outRead = null;
		try {
			outRead = new PrintWriter(new FileWriter(readLog, true));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		PrintWriter outFaultLog = null;
		try {
			outFaultLog = new PrintWriter(new FileWriter(pageFautlLog, true));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    for (int i = 0; i < processSize; i++) {
	    	Page tempPage = null;
	    	int randomOps = (int) (Math.random() * 2);
	        if(init == 0){
	        	
	        	int initialization = (int) (Math.random() * MEMORY_SIZE);
	        	//value = onePlace.requestPage();
	        	//tempPage = onePlaceLRU.requestPage(initialization);
	        	//tempPage = onePlace.requestPage(initialization);
	        	tempPage = onePlaceRandom.requestPage(initialization);
	        	value = tempPage.id;
	        	pagesIndex.add(tempPage);
	        	//value = onePlaceWSClock.requestPage();
	        	//value = onePlaceRandom.requestPage();
	        	reads++;
	            System.out.println("Process #" + this.number + " first time in memory got id: " + value);
	          	outRead.append("Process #" + this.number + " first time in memory got id: " + value  + "\n");
	          	outRead.append("Process #" + this.number + " total read: " + reads  + "\n");
	          	outLog.append("Process #" + this.number + " first time in memory got id: " + value  + "\n");	
				
	          	init++;
	        }
	    	if(randomOps == 1){
	            int index =	(int) (Math.random() * pagesIndex.size());
	        	//int readPageId = onePlace.readPage(index);
	            tempPage = pagesIndex.get(index);
	            //Page checkPage = onePlaceLRU.readPage(tempPage);
	            Page checkPage = onePlaceRandom.readPage(tempPage);
	            if(checkPage == null){
	            	faults++;
	            	System.out.println("Process #" + this.number + " page fault" + " requested page id " + tempPage.id);
	            	outFaultLog.append("Process #" + this.number + " page fault" + " requested page id " + tempPage.id + "\n");
	            	outFaultLog.append("Process #" + this.number + " page fault total: " + faults +  "\n");
	            	outLog.append("Process #" + this.number + " page fault" + " requested page id " + tempPage.id + "\n");
	            	
	            	//checkPage = onePlaceLRU.requestPage(tempPage.id);
	            	checkPage = onePlaceRandom.requestPage(tempPage.id);
	            }
	            
	            //int readPageId = onePlaceLRU.readPage(checkPage).id;
	            int readPageId = onePlaceRandom.readPage(checkPage).id;
	        	reads++;
	        	System.out.println("Process #" + this.number + " reading page id: " + readPageId);
	        	outRead.append("Process #" + this.number + " reading page id: " + value + "\n");
	        	outLog.append("Process #" + this.number + " reading page id: " + value + "\n");
	        	outRead.append("Process #" + this.number + " total read: " + reads  + "\n");
	        	value = readPageId;
	        
	    	}else{
	            
	    		int initialization = (int) (Math.random() * MEMORY_SIZE);
	          	//value = onePlace.requestPage();
	    		//tempPage = onePlaceLRU.requestPage(initialization);
	    		tempPage = onePlaceRandom.requestPage(initialization);
	    		pagesIndex.add(tempPage);
	          	value = tempPage.id;
	          	writes++;
	          	//value = onePlaceWSClock.requestPage();
	          	//value = onePlaceRandom.requestPage();
	          	//System.out.println("requested page");
	          	outRead.append("Process #" + this.number + " total writes: " + writes  + "\n");
	          	System.out.println("Process #" + this.number + " requested page got id: " + value);
	          	outWrite.append("Process #" + this.number + " requested page got id: " + value + "\n");
	          	outLog.append("Process #" + this.number + " requested page got id: " + value + "\n");
	          	
	        }
	            
	    }
	    outFaultLog.close();
	    outRead.close();
	    outWrite.close();
	    outLog.close();
	}
	
}
